.\" Copyright (c) 2019 Charles A. Daniels <charles@cdaniels.net>
.\" Copyright (c) 2009-2019 Julien Nadeau Carriere <vedge@csoft.net>
.\" All rights reserved.
.\"
.\" Redistribution and use in source and binary forms, with or without
.\" modification, are permitted provided that the following conditions
.\" are met:
.\" 1. Redistributions of source code must retain the above copyright
.\"    notice, this list of conditions and the following disclaimer.
.\" 2. Redistributions in binary form must reproduce the above copyright
.\"    notice, this list of conditions and the following disclaimer in the
.\"    documentation and/or other materials provided with the distribution.
.\"
.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
.\" IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
.\" WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
.\" INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
.\" (INCLUDING BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
.\" SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
.\" IN ANY WAY OUT OF THE USE OF THIS SOFTWARE EVEN IF ADVISED OF THE
.\" POSSIBILITY OF SUCH DAMAGE.
.\"
.Dd September 13, 2009
.Dt AG_WIDGETPRIMITIVES 3
.Os
.ds vT Agar API Reference
.ds oS Agar 1.4
.Sh NAME
.Nm AG_WidgetPrimitives
.Nd agar widget rendering primitives
.Sh SYNOPSIS
.Bd -literal
#include <agar/core.h>
#include <agar/gui.h>
.Ed
.Sh DESCRIPTION
Agar provides a set of graphical primitives that may be called from the
.Fn draw
method of an
.Xr AG_Widget 3
("rendering context").
.Pp
Although these functions draw directly to the display, they take
.Fa x
and
.Fa y
coordinates in the local coordinate system of the
.Fa widget .
.Sh LOW-LEVEL PRIMITIVES
The following routines render directly to the display, converting relative
.Fa x ,
.Fa y
coordinates to display coordinates implicitely.
.Pp
.nr nS 1
.Ft void
.Fn AG_PutPixel "AG_Widget *widget" "int x" "int y" "const AG_Color *c"
.Pp
.Ft void
.Fn AG_PutPixelRGB "AG_Widget *widget" "int x" "int y" "AG_Component r" "AG_Component g" "AG_Component b"
.Pp
.Ft void
.Fn AG_PutPixelRGB_8 "AG_Widget *widget" "int x" "int y" "Uint8 r" "Uint8 g" "Uint8 b"
.Pp
.Ft void
.Fn AG_PutPixelRGB_16 "AG_Widget *widget" "int x" "int y" "Uint16 r" "Uint16 g" "Uint16 b"
.Pp
.Ft void
.Fn AG_PutPixel32 "AG_Widget *widget" "int x" "int y" "Uint32 px"
.Pp
.Ft void
.Fn AG_PutPixel64 "AG_Widget *widget" "int x" "int y" "Uint64 px"
.Pp
.Ft void
.Fn AG_BlendPixel "AG_Widget *widget" "int x" "int y" "const AG_Color *c" "AG_AlphaFn blendFn"
.Pp
.Ft void
.Fn AG_BlendPixel32 "AG_Widget *widget" "int x" "int y" "Uint32 c" "AG_AlphaFn blendFn"
.Pp
.Ft void
.Fn AG_BlendPixel64 "AG_Widget *widget" "int x" "int y" "Uint64 c" "AG_AlphaFn blendFn"
.Pp
.Ft void
.Fn AG_DrawCircle "AG_Widget *widget" "int x" "int y" "int radius" "const AG_Color *c"
.Pp
.Ft void
.Fn AG_DrawCircle2 "AG_Widget *widget" "int x" "int y" "int radius" "const AG_Color *c"
.Pp
.Ft void
.Fn AG_DrawLine "AG_Widget *widget" "int x1" "int y1" "int x2" "int y2" "const AG_Color *c"
.Pp
.Ft void
.Fn AG_DrawLineBlended "AG_Widget *widget" "int x1" "int y1" "int x2" "int y2" "Uint8 c[4]" "AG_AlphaFn fnSrc" "AG_AlphaFn fnDst"
.Pp
.Ft void
.Fn AG_DrawLineW "AG_Widget *widget" "int x1" "int y1" "int x2" "int y2" "const AG_Color *c" "float width"
.Pp
.Ft void
.Fn AG_DrawLineW_Sti16 "AG_Widget *widget" "int x1" "int y1" "int x2" "int y2" "const AG_Color *c" "float width" "Uint16 stipple"
.Pp
.Ft void
.Fn AG_DrawLineH "AG_Widget *widget" "int x1" "int x2" "int y" "const AG_Color *c"
.Pp
.Ft void
.Fn AG_DrawLineV "AG_Widget *widget" "int x" "int y1" "int y2" "const AG_Color *c"
.Pp
.Ft void
.Fn AG_DrawRect "AG_Widget *widget" "const AG_Rect *r" "const AG_Color *c"
.Pp
.Ft void
.Fn AG_DrawRectOutline "AG_Widget *widget" "const AG_Rect *r" "const AG_Color *c"
.Pp
.Ft void
.Fn AG_DrawRectFilled "AG_Widget *widget" "const AG_Rect *r" "const AG_Color *c"
.Pp
.Ft void
.Fn AG_DrawRectBlended "AG_Widget *widget" "const AG_Rect *r" "const AG_Color *c" "AG_AlphaFn fnSrc" "AG_AlphaFn fnDst"
.Pp
.Ft void
.Fn AG_DrawArrowLine "AG_Widget *widget" "int x1" "int y1" "int x2" "int y2" "AG_ArrowLineType t" "int length" "double theta" "const AG_Color *c"
.Pp
.nr nS 0
.Fn AG_PutPixel
sets the pixel at
.Fa x ,
.Fa y
to the native display color that most closely matches the given
.Xr AG_Color 3 .
The
.Fn AG_PutPixelRGB ,
.Fn AG_PutPixelRGB_8 ,
and
.Fn AG_PutPixelRGB_16
forms accept component values as separate arguments.
.Pp
The
.Fn AG_PutPixel32
form accept an 8- to 32-bit wide pixel already in native display format.
Under
.Dv AG_LARGE ,
the
.Fn AG_PutPixel64
form also allows 48- and 64-bit wide pixel values.
.Pp
The
.Fn AG_BlendPixel
function blends an existing pixel against a given
.Xr AG_Color 3 ,
overwriting the pixel with the best native-display approximation of the result.
The
.Fn AG_BlendPixel32
and
.Fn AG_BlendPixel64
variants take a 32- and a 64-bit pixel value respectively.
.Pp
Coordinates to
.Fn AG_PutPixel*
and
.Fn AG_BlendPixel*
are checked, and intersected against active clipping rectangles (see
.Xr AG_Widget 3 ) .
.Pp
.Fn AG_DrawFrame
draws a 3D raised box (if z>0) or a 3D well (if z<0).
.Pp
.Fn AG_DrawCircle
draws a circle around
.Fa x ,
.Fa y
of
.Fa radius
pixels.
.Pp
.Fn AG_DrawLine
draws a line segment from point
.Fa x1 ,
.Fa y1
to
.Fa x2 ,
.Fa y2 .
.Pp
.Fn AG_DrawLineH
draws a horizontal line from point
.Fa x ,
.Fa y1
to
.Fa x ,
.Fa y2 .
.Pp
.Fn AG_DrawLineV
draws a vertical line from point
.Fa x1 ,
.Fa y
to
.Fa x2 ,
.Fa y .
.Pp
.Fn AG_DrawLineW
draws a line of specified
.Fa width
(where 1.0f = 1 pixel) between
.Fa x1 ,
.Fa y1
and
.Fa x2 ,
.Fa y2 .
.Pp
.Fn AG_DrawLineW_Sti16
draws a line of specified
.Fa width
(where 1.0f = 1 pixel)
and 16-bit
.Fa stipple
pattern between
.Fa x1 ,
.Fa y1
and
.Fa x2 ,
.Fa y2 .
.Pp
The
.Fn AG_DrawLineBlended
variant performs alpha blending if the alpha component of
.Fa c
is not fully opaque.
.Pp
The
.Fn AG_DrawRect
function fills a destination rectangle with the specified color.
If the color is non-opaque, blending is performed.
.Pp
.Fn AG_DrawRectOutline
draws the outline of a rectangle.
.Pp
.Fn AG_DrawRectFilled
fills an opaque rectangle with the specified color, ignoring any alpha
component.
.Pp
.Fn AG_DrawRectBlended
draws a blended rectangle of the color
.Fa c .
.Fa fnSrc
specifies the source factor (e.g.,
.Dv AG_ALPHA_SRC )
and
.Fa fnDst
the destination factor (e.g.,
.Dv AG_ALPHA_ONE_MINUS_SRC ) .
For the list of available functions, refer to
.Xr AG_AlphaFn 3 .
.Pp
.Fn AG_DrawArrowLine
is a wrapper around
.Fn AG_DrawLine
and
.Fn AG_DrawArrowhead
which can draw a line along with, depending on the value of
.Fa t :
.Pp
.Bl -tag -width "AG_ARROWLINE_FORWARD " -compact
.It AG_ARROWLINE_NONE
No arrowheads.
.It AG_ARROWLINE_FORWARD
A forward-pointing arrow.
.It AG_ARROWLINE_REVERSE
A reverse-pointing arrow.
.It AG_ARROWLINE_BOTH
Forward and reverse arrows.
.El
.Pp
For the purposes of determining "forward" and "reverse", a forward arrow would
be taken to point to (
.Fa x2,
.Fa y2
).
.Sh HIGH-LEVEL PRIMITIVES
The following functions call low-level primitives in order to produce
3D-style features.
Unlike low-level primitives (which are stateless), these functions allow the
state of
.Fa widget
to influence the appearance (for example, adding dither patterns if
the widget is in #disabled state).
.Pp
.nr nS 1
.Ft void
.Fn AG_DrawBoxRaised "AG_Widget *widget" "const AG_Rect *r" "const AG_Color *c"
.Pp
.Ft void
.Fn AG_DrawBoxSunk "AG_Widget *widget" "const AG_Rect *r" "const AG_Color *c"
.Pp
.Ft void
.Fn AG_DrawBox "AG_Widget *widget" "const AG_Rect *r" "int z" "const AG_Color *c"
.Pp
.Ft void
.Fn AG_DrawBoxRounded "AG_Widget *widget" "const AG_Rect *r" "int z" "int radius" "const AG_Color *c"
.Pp
.Ft void
.Fn AG_DrawBoxRoundedTop "AG_Widget *widget" "const AG_Rect *r" "int z" "int radius" "const AG_Color *c"
.Pp
.Ft void
.Fn AG_DrawFrame "AG_Widget *widget" "const AG_Rect *r" "int z" "const AG_Color *c"
.Pp
.nr nS 0
The
.Fn AG_DrawBoxRaised
routine renders a 3D-style raised box over the area of
.Fa r .
.Fn AG_DrawBoxSunk
renders a 3D-style well.
.Pp
.Fn AG_DrawBox
invokes
.Fn AG_DrawBoxRaised
or
.Fn AG_DrawBoxSunk
based on the
.Fa z
argument.
The magnitude of
.Fa z
determines the depth of the box.
.Pp
.Fn AG_DrawBoxRounded
renders a box with the edges rounded to the given
.Fa radius .
The
.Fn AG_DrawBoxRoundedTop
variant only rounds the top two corners.
.Pp
.Sh SYMBOLS
.nr nS 1
.Ft void
.Fn AG_DrawTriangle "AG_Widget *widget" "AG_Pt v1" "AG_Pt v2" "AG_Pt v3" "const AG_Color *c"
.Pp
.Ft void
.Fn AG_DrawPolygon "AG_Widget *widget" "const AG_Pt *pts" "Uint nPts" "const AG_Color *c"
.Pp
.Ft void
.Fn AG_DrawPolygon_Sti32 "AG_Widget *widget" "const AG_Pt *pts" "Uint nPts" "const AG_Color *c" "const Uint8 *stipplePattern"
.Pp
.Ft void
.Fn AG_DrawVector "AG_Widget *widget" "int dim" "const AG_Rect *r" "const AG_VectorElement *elements" "int elemFirst" "int elemLast"
.Pp
.Ft void
.Fn AG_DrawArrowUp "AG_Widget *widget" "int x" "int y" "int h" "const AG_Color *c1" "const AG_Color *c2"
.Pp
.Ft void
.Fn AG_DrawArrowDown "AG_Widget *widget" "int x" "int y" "int h" "const AG_Color *c1" "const AG_Color *c2"
.Pp
.Ft void
.Fn AG_DrawArrowLeft "AG_Widget *widget" "int x" "int y" "int w" "const AG_Color *c1" "const AG_Color *c2"
.Pp
.Ft void
.Fn AG_DrawArrowRight "AG_Widget *widget" "int x" "int y" "int w" "const AG_Color *c1" "const AG_Color *c2"
.Pp
.Ft void
.Fn AG_DrawArrowhead "void *obj" "int x1" "int y1" "int x2" "int y2" "int length" "double theta" "const AG_Color *c"
.Pp
.nr nS 0
.Fn AG_DrawTriangle
renders a triangle of color
.Fa c
given three unordered vertices
.Fa v1 ,
.Fa v2 ,
and
.Fa v3 .
.Pp
.Fn AG_DrawPolygon
draws a convex polygon of color
.Fa c
from an array of vertices
.Fa pts .
.Fn AG_DrawPolygonSti32
renders a convex polygon of color
.Fa c
from an array of vertices
.Fa pts
and a 32x32 bitmask (or 1-bpp image).
.Fa stipplePattern
must point to a 128-byte (32 x 4 byte) array.
.Pp
.Fn AG_DrawArrowUp ,
.Fn AG_DrawArrowDown ,
.Fn AG_DrawArrowLeft
and
.Fn AG_DrawArrowRight
draw an arrow at the specified coordinates.
.Fa h
and
.Fa w
specify the size of the arrow in pixels.
.Pp
.Fn AG_DrawArrowhead
draws an arrowhead aligned to a line.
.Fa x2
and
.Fa y2
Define the tip of the arrowhead, and
.Fa x1
and
.Fa y1
define the originating point of the "line" (i.e. the arrowhead faces away from
this point).
.Fa length
defines the length from tip to base of the arrowhead.
.Fa theta
defines the angle of the lines which converge at the tip of the arrowhead. The
arrowhead is always drawn in a solid / fully filled style.
.Sh UTILITY ROUTINES
.nr nS 1
.Ft int
.Fn AG_GetLineIntersection "long x1" "long y1" "long x2" "long y2" "long x3" "long y3" "long x4" "long y4" "long *xi" "long *yi"
.Pp
.Ft void
.Fn AG_ClipLine "int ax" "int ay" "int aw" "int ah" "int x1" "int y1" "int *x2" "int *y2"
.Pp
.Ft void
.Fn AG_ClipLineCircle "int xc" "int yc" "int r" "int x1" "int y1" "int x2" "int y2" "int *xi" "int *yi"
.Pp
.nr nS 0
.Pp
The
.Fn AG_GetLineIntersection
function considers two line segments (
.Fa x1,
.Fa y1
), (
.Fa x2,
.Fa y2
) and (
.Fa x3,
.Fa y3
) and (
.Fa x4,
.Fa y4
). If the lines do not intersect, then the function returns 0. If they do
intersect, then it returns 1 and
.Fa xi
and
.Fa yi
will be updated to the coordinates at which the intersection occurs.
.Pp
.Fn AG_ClipLine
considers the bounding box defined by it's top left corner:
.Fa ax,
.Fa ay
and its width and height:
.Fa aw,
.Fa ah
and the line segment defined by (
.Fa x1,
.Fa y1,
), (
.Fa x2,
.Fa y2,
). If the line intersects with the provided bounding box, then
.Fa x2
and
.Fa y2
will be updated such that they are the closest point to (
.Fa x1,
.Fa y1
) at which the line segment intersects with the given bounding box.
.Pp
.Fn AG_ClipLine
If the circle centered at (
.Fa xc,
.Fa yc
) with radius
.Fa r
intersects with the line segment (
.Fa x1,
.Fa y1
), (
.Fa x2,
.Fa y2
), then
.Fa xi
and
.Fa yi
are updated to reflect the intersection point which is closest to
(
.Fa x1,
.Fa y1
).
.Sh SEE ALSO
.Xr AG_AlphaFn 3 ,
.Xr AG_Color 3 ,
.Xr AG_Intro 3 ,
.Xr AG_Widget 3 ,
.Xr RG 3 ,
.Xr VG 3
.Sh HISTORY
Simple widget primitives first appeared in Agar 1.0.
The basic rendering system was redesigned in Agar 1.4.0.
64-bit pixel access routines, line intersection/clipping tests and the
Arrowhead primitive were added in Agar 1.6.0.
